﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Messaging;
using System.Windows;
using MsmqView.Core.Configuration;
using MsmqView.Core.Messaging;
using MsmqView.UI.EventArgs;
using MsmqView.UI.Views;

namespace MsmqView.UI.Controllers
{
	public interface IMsmqViewMainController { }

	public class MsmqViewMainController : IMsmqViewMainController
	{
		#region Private Fields
		private readonly IMsmqViewMainView view;
		private readonly IEnvironmentConfiguration environment;
		private readonly IMessageQueueGateway gateway;

		private IEnumerable<MessageQueue> machineQueues;
		private MessageQueue selectedQueue;
		private Message selectedMessage;
		#endregion

		#region Constructors
		public MsmqViewMainController(IMsmqViewMainView view, IEnvironmentConfiguration environment, IMessageQueueGateway gateway)
		{
			this.view = view;
			this.environment = environment;
			this.gateway = gateway;

			view.Loaded += new RoutedEventHandler(view_Loaded);
			view.MachineSelected += new EventHandler<MachineSelectedEventArgs>(view_MachineSelected);
			view.MessageSelected += new EventHandler<MessageSelectedEventArgs>(view_MessageSelected);
			view.QueueSelected += new EventHandler<QueueSelectedEventArgs>(view_QueueSelected);
		}
		#endregion

		#region Event Handlers
		private void view_Loaded(object sender, RoutedEventArgs e)
		{
			view.DisplayMachineName(environment.MachineName);
		}

		private void view_MachineSelected(object sender, MachineSelectedEventArgs e)
		{
			ClearError();
			machineQueues = new MessageQueue[] { };

			try
			{
				machineQueues = gateway.GetPrivateQueuesByMachineName(e.SelectedMachineName);
			}
			catch (MessageQueueException messageQueueException)
			{
				view.DisplayError(messageQueueException.Message);
			}
			catch (ArgumentException argumentException)
			{
				view.DisplayError(argumentException.Message);
			}

			view.DisplayQueues(
					from queue in machineQueues
					select new QueueName(queue.QueueName, environment.PrivateQueueQualifier)
				);			
		}

		private void view_QueueSelected(object sender, QueueSelectedEventArgs e)
		{
			selectedMessage = null;

			selectedQueue = (from queue in machineQueues
							 where queue.QueueName == e.SelectedQueue.FullName
							 select queue).SingleOrDefault();

			view.DisplayMessages(
					from message in selectedQueue.GetAllMessages()
					select new MessageIdentifier(message.Id)
				);

			view.DisplayMessageBody(String.Empty);
		}

		private void view_MessageSelected(object sender, MessageSelectedEventArgs e)
		{
			selectedMessage = (from message in selectedQueue.GetAllMessages()
							   where message.Id == e.SelectedMessageIdentifier.FullIdentifier
							   select message).SingleOrDefault();

			var messageBodyFormatter = new PlainXmlMessageFormatter();
			var messageBody = messageBodyFormatter.Read(selectedMessage).ToString();

			view.DisplayMessageBody(messageBody);
		}
		#endregion

		#region Private Methods
		private void ClearError()
		{
			view.DisplayError(String.Empty);
		}
		#endregion
	}
}
